/*
 * VideoBehavior.java
 *
 * Created on 24 de abril de 2007, 10:12 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

import javax.media.j3d.*;
import javax.vecmath.*;
import java.util.Enumeration;

/**
 *
 * @author William Santamaria
 */

public class VideoBehavior extends Behavior {
	
    final int rt = 500;
    private TransformGroup tg;
    private QuadArray qa;
    private double rot_sup;
    private double inc_sup;
    private double inc_med;
    private double rot_cam;
    private Transform3D t3d = new Transform3D();
    private Point3d p_med = new Point3d();
    private Point3d p_cam = new Point3d();
    private Vector3d v_cam = new Vector3d();
    private Point3d eye = new Point3d();
    private Point3d center = new Point3d();

    public VideoBehavior(TransformGroup tg, QuadArray qa){
        this.tg = tg;
        this.qa = qa;
    }

    public void initialize(){
        
        setCamara();
        setPlano();
        
        this.wakeupOn(new WakeupOnElapsedTime(rt));
    }

    public void processStimulus(Enumeration criteria){

        setCamara();
        setPlano();

        this.wakeupOn(new WakeupOnElapsedTime(rt));
    }

    public void setCamara(){
        calcularPmed();
        calcularPcam();
        calcularVcam();
        eye = pdv( p_cam,2,v_cam );
        center = pdv( p_cam,4,v_cam );
        t3d.lookAt( eye, center, getUcam() );
        tg.setTransform(t3d);
    }
    
    public void setPlano(){
        double rot = rot_sup+180;
        Vector3d v = calcularVector( rot, -inc_sup+inc_med );
        Point3d p = pdv(p_cam,1,v_cam);

        double d = p_med.distance( new Point3d(0,0,0) );
        //System.out.println(d);
        d = 1;//((9-d)*.03)+.5;
        double cr = d*Math.cos( Math.toRadians(rot_cam+45) );
        double sr = d*Math.sin( Math.toRadians(rot_cam+45) );

        qa.setCoordinate(0, pdv( pda(p,cr,rot),-sr,v ) );
        qa.setCoordinate(1, pdv( pda(p,sr,rot),cr,v ) );
        qa.setCoordinate(2, pdv( pda(p,-cr,rot),sr,v ) );
        qa.setCoordinate(3, pdv( pda(p,-sr,rot),-cr,v ) );
    }
    
    public void setAngulos(double rot_sup, double inc_sup, double inc_med, double rot_cam){
        this.rot_sup = rot_sup;
        this.inc_sup = inc_sup;
        this.inc_med = inc_med;
        this.rot_cam = rot_cam;
    }

    public void calcularPmed(){
        p_med.x = Podio.p_sup.x+( Podio.largo_bra_sup*Math.sin( Math.toRadians(inc_sup) )*Math.cos( Math.toRadians(rot_sup) ) );
        p_med.y = Podio.p_sup.y-( Podio.largo_bra_sup*Math.cos( Math.toRadians(inc_sup) ) );
        p_med.z = Podio.p_sup.z+( Podio.largo_bra_sup*Math.sin( Math.toRadians(inc_sup) )*Math.sin( Math.toRadians(rot_sup) ) );
    }

    public void calcularPcam(){
        p_cam.x = p_med.x+( (Podio.largo_bra_inf+Podio.largo_camara)*Math.sin( Math.toRadians(inc_sup-inc_med) )*Math.cos( Math.toRadians(rot_sup) ) );
        p_cam.y = p_med.y-( (Podio.largo_bra_inf+Podio.largo_camara)*Math.cos( Math.toRadians(inc_sup-inc_med) ) );
        p_cam.z = p_med.z+( (Podio.largo_bra_inf+Podio.largo_camara)*Math.sin( Math.toRadians(inc_sup-inc_med) )*Math.sin( Math.toRadians(rot_sup) ) );
        //System.out.println("x="+p_cam.x+" y="+p_cam.y+" z="+p_cam.z);
    }

    public void calcularVcam(){
        v_cam = new Vector3d( p_cam.x-p_med.x,p_cam.y-p_med.y,p_cam.z-p_med.z );
        v_cam.normalize();
    }
    
    public Vector3d getUcam() { 
        Vector3d u_cam = new Vector3d();

        double cr = Math.cos( Math.toRadians(rot_cam) );
        double sr = Math.sin( Math.toRadians(rot_cam) );
        Vector3d v = calcularVector( rot_sup, inc_sup-inc_med );
        v.negate();
        Point3d p = pdv( pda(p_cam,-sr,rot_sup),cr,v );

        u_cam.x = p.x-p_cam.x;
        u_cam.y = p.y-p_cam.y;
        u_cam.z = p.z-p_cam.z;
        u_cam.normalize();
    	return u_cam; 
    }

    public Point3d pdv(Point3d p, double d, Vector3d v){
        p = new Point3d( p.x+d*v.x,p.y+d*v.y,p.z+d*v.z );
        return p;
    }
    
    public Point3d pda(Point3d p, double d, double a){
        p = new Point3d( p.x+d*Math.sin(-Math.toRadians(a)),p.y,p.z+d*Math.cos(-Math.toRadians(a)) );
        return p;
    }

    public Vector3d calcularVector( double rot, double inc ){
        Vector3d v = new Vector3d();
        v.x = Math.cos( Math.toRadians(rot) )*Math.cos( Math.toRadians(inc) );
        v.y = Math.sin( Math.toRadians(inc) );
        v.z = Math.sin( Math.toRadians(rot) )*Math.cos( Math.toRadians(inc) );
        return v;
    }

}
